package com.kira.scaffoldmvc.Service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kira.scaffoldmvc.Mapper.BookMapper;
import com.kira.scaffoldmvc.Mapper.UserMapper;
import com.kira.scaffoldmvc.POJO.*;
import com.kira.scaffoldmvc.POJO.DTO.BookDTO;
import com.kira.scaffoldmvc.POJO.DTO.DetailDTO;
import com.kira.scaffoldmvc.POJO.DTO.GetTotalDTO;
import com.kira.scaffoldmvc.POJO.DTO.UpdateDTO;
import com.kira.scaffoldmvc.Service.BookService;
import com.kira.scaffoldmvc.Utils.RandomGenerator;
import com.kira.scaffoldmvc.Utils.ThreadLocalUtil;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private UserMapper userMapper;

    @Override
    public BookIsbn getByISBN(String isbn) {


        Detail byISBN = bookMapper.getByISBN(isbn);
        DetailDTO dto = new DetailDTO();
        BookIsbn bookIsbn = new BookIsbn();
        if (byISBN == null) {
            return bookIsbn;
        }

        dto.setISBN(byISBN.getISBN());
        dto.setId(byISBN.getBookId());
        dto.setName(byISBN.getBookName());
        dto.setAuthor(byISBN.getAuthor());
        dto.setDescription(byISBN.getIntroduce());
        dto.setPublisher(byISBN.getPublish());


        bookIsbn.setDetail(dto);
        bookIsbn.setCode("200");
        bookIsbn.setISBN(isbn);
        return bookIsbn;

    }

    //得到各类型的书的总数
    @Override
    public Result<List<GetTotalDTO>> getTotal() {

        List<GetTotalDTO> total = bookMapper.getTotal();


        return Result.success(total);


    }

    @Override
    public Result getRentCurrentRecord(@RequestParam Date date, @RequestParam Integer Type) {
        return null;
    }

    @Override
    public Result batchBookInsert(@RequestParam Book book) {
        return null;
    }


    @Override
    public Result<PageBean<Book>> getAllBook(Integer pageNum, Integer pageSize) {
        PageBean<Book> pb = new PageBean<>();
        PageHelper.startPage(pageNum, pageSize);

        List<Book> books = bookMapper.getAllBook();
        PageInfo<Book> page = new PageInfo<>(books);
        pb.setTotal(page.getTotal());
        pb.setItems(page.getList());

        return Result.success(pb);
    }

    //书转出
    @Override
    public Result Bookout(@RequestParam String bookId) {
        Map<String, Object> claims = ThreadLocalUtil.get();
        String myUserId = (String) claims.get("userId");
        Integer myRight = userMapper.selectRight(myUserId);
        if (myRight == 1 || myRight == 2) {

        } else
            return Result.error("该用户不是管理员用户");
        bookMapper.changeBookStatus(bookId, 2);
        return Result.success("书籍成功转出");
    }


    //借书
    //修改书的状态,生成借书记录
    @Transactional
    @Override
    public Result rentBook(@RequestParam String bookId) {

        Book book = bookMapper.getBookById(bookId);
        //判断用户是否是黑名单用户
        Map<String, Object> claims = ThreadLocalUtil.get();
        String userId = (String) claims.get("userId");
        User user = userMapper.getUserById(userId);//通过用户Id来判断这个是否是黑名但用户
        if (user.getBan() == 1) {
            return Result.error("你已被拉进黑名单,请联系管理员");
        }

        long startTime = System.currentTimeMillis();
        if (book.getStatus() != 0)//说明这本书不在图书馆或者被借出
        {
            return Result.success("该书目前不在");
        }


        String rentId = RandomGenerator.generateRandom(6);//生成唯一的bookId
//        bookMapper.rentBook(bookId, rentId, userId, book.getBookName());
//        bookMapper.changeBookStatus(bookId,1);
        CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
            bookMapper.rentBook(bookId, rentId, userId, book.getBookName());
            return "借书成功记录";
        }).exceptionally(e -> "报错");

        CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
            bookMapper.changeBookStatus(bookId, 1);
            return "成功改变借书状态";
        }).exceptionally(e -> "报错");

        cf1.join();
        cf2.join();
        long endTime = System.currentTimeMillis();
        return Result.success("成功借书,接口耗费时间" + (endTime - startTime));
    }

    //还书
    @Transactional
    @Override
    public Result backBook(@RequestParam String bookId, @RequestParam String rentId) {
        CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
            bookMapper.backBook(rentId);
            return "还书成功";
        }).exceptionally(e -> "报错");

        CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
            bookMapper.changeBookStatus(bookId, 0);
            return "修改借阅记录";
        }).exceptionally(e -> "报错");


        return Result.success("成功还书");
    }

    @Override
    public Result InsertBook(Book book) {
        Map<String, Object> claims = ThreadLocalUtil.get();
        String myUserId = (String) claims.get("userId");
        Integer myRight = userMapper.selectRight(myUserId);
        if (myRight == 1 || myRight == 2) {

        } else
            return Result.error("该用户不是管理员用户");
        //生成的我们的BookId
        String bookId = RandomGenerator.generateRandom(6);
        book.setBookId(bookId);
        book.setStatus(0);//默认设置未没借出
        bookMapper.InsertBook(book);
        log.info("录入成功");

        return Result.success("书籍录入成功");
    }

    //得到用户借阅记录的分页查询
    @Override
    public Result<PageBean<RentBook>> getHistory(@RequestParam String userId, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
        PageBean<RentBook> pb = new PageBean<>();
        PageHelper.startPage(pageNum, pageSize);

        List<RentBook> rentBooks = bookMapper.getHistoryById(userId);


        PageInfo<RentBook> page = new PageInfo<>(rentBooks);
        pb.setTotal(page.getTotal());
        pb.setItems(page.getList());

        return Result.success(pb);
    }


    @Override
    public Result getBook(String bookId) {
        Book book = bookMapper.getBookById(bookId);
        return Result.success(book);
    }

    @Override
    public Result updateBook(UpdateDTO dto) {
        Map<String, Object> claims = ThreadLocalUtil.get();
        String myUserId = (String) claims.get("userId");
        Integer myRight = userMapper.selectRight(myUserId);
        if (myRight == 1 || myRight == 2) {

        } else
            return Result.error("该用户不是管理员用户");

        Book book1 = bookMapper.getBookById(dto.getBookId());
        if (book1 == null)
            return Result.error("这本书不存在");

        BookDTO book = new BookDTO();
        book.setBookName(dto.getBook().getBookName());
        book.setHot(dto.getBook().getHot());
        book.setType(dto.getBook().getType());
        book.setPublish(dto.getBook().getPublish());
        book.setStatus(dto.getBook().getStatus());
        book.setAuthor(dto.getBook().getAuthor());
        book.setIntroduce(dto.getBook().getIntroduce());
        book.setLocation(dto.getBook().getLocation());
        book.setIsbn(dto.getBook().getIsbn());

        bookMapper.updateBook(book, dto.getBookId());
        return Result.success("成功修改");
    }

    @Override
    public Result getRent(Integer pageNum, Integer pageSize) {


        Map<String, Object> claims = ThreadLocalUtil.get();
        String myUserId = (String) claims.get("userId");
        Integer myRight = userMapper.selectRight(myUserId);
        if (myRight == 1 || myRight == 2) {

        } else
            return Result.error("该用户不是管理员用户");
        PageBean<RentBook> pb = new PageBean<>();
        PageHelper.startPage(pageNum, pageSize);

        List<RentBook> rentBooks = bookMapper.getRent();


        PageInfo<RentBook> page = new PageInfo<>(rentBooks);
        pb.setTotal(page.getTotal());
        pb.setItems(page.getList());
        return Result.success(pb);
    }
}
